﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ApiListener
{
    public class ServerListener: IDisposable
    {
        int _port;
        public ServerListener(int port)
        {
            _port = port;
        }
        HttpListener httpListenner;
        Thread thread;
        public void Start()
        {
            httpListenner = new HttpListener();
            httpListenner.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
            var url = $"http://127.0.0.1:{_port}/";
            httpListenner.Prefixes.Add(url);
            httpListenner.Start();
            Console.WriteLine($"HttpListener {url}");
            Console.Title = $"HttpListener {url}";
            thread = new Thread(new ThreadStart(() =>
              {
                  while (true)
                  {
                      HttpListenerContext context = httpListenner.GetContext();
                      try
                      {
                          OnRequest(context);
                      }
                      catch (Exception ero)
                      {
                          Console.WriteLine("Listenn error :" + ero.Message);
                          context.Response.Close();
                      }
                  }
              }));
            thread.Start();

        }

        void OnRequest(HttpListenerContext httpContext)
        {
            var request = httpContext.Request;
            var response = httpContext.Response;
            var lines = new Dictionary<string, string>();
            var path = request.Url.ToString();
            lines.Add("Url", path);
            lines.Add("Method", request.HttpMethod);
            if (request.ContentLength64 > 0)
            {
                var ms = request.InputStream;
                var data = new byte[request.ContentLength64];
                ms.Read(data, 0, data.Length);
                var args = System.Text.Encoding.UTF8.GetString(data);
                lines.Add("Body", args);
            }
            var removeKeys = new List<string>() { "Cache-Control", "Connection", "Accept", "Accept-Encoding" , "Cookie" };
            foreach (var key in request.Headers.Keys)
            {
                if (removeKeys.Contains(key.ToString()))
                {
                    continue;
                }
                var v = request.Headers[key.ToString()];
                if(!string.IsNullOrEmpty(v))
                {
                    lines.Add($"Header {key.ToString()}", v);
                }
            }
            var cookies = request.Cookies;
            foreach (Cookie c in cookies)
            {
                lines.Add($"Cookie {c.Name}", c.Value);
            }
            lines.Add("IP", request.RemoteEndPoint.Address.MapToIPv4().ToString());
            var lines2 = lines.Select(b => $"{b.Key}: {b.Value}");
            var str = string.Join("\r\n", lines2);
            Console.WriteLine(str);
            Console.WriteLine("------------------------end------------------------");
            var res = Encoding.UTF8.GetBytes(str);
            response.OutputStream.Write(res, 0, res.Length);
            response.Close();
        }
        public void Dispose()
        {
            if (httpListenner != null)
            {
                httpListenner.Abort();
            }
            if (thread != null)
            {
                thread.Abort();
            }
        }
    }

}
